/*
 * Open Source Physics software is free software as described near the bottom of this code file.
 *
 * For additional information and documentation on Open Source Physics please see:
 * <http://www.opensourcephysics.org/>
 */

package org.opensourcephysics.tools;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;

/**
 * A checkbox mouse and tree selection listener.
 *
 * @author Douglas Brown
 *
 * Based on code by Santhosh Kumar T - santhosh@in.fiorano.com
 * See http://www.jroller.com/page/santhosh/20050610
 */
public class CheckTreeManager
		extends MouseAdapter
		implements TreeSelectionListener, MouseMotionListener {

	private CheckTreeSelectionModel selectionModel;
	private JTree tree = new JTree();
	int hotspot = new JCheckBox().getPreferredSize().width;
	boolean ignoreEvents = false;

  /**
   * Constructor.
   *
   * @param tree a JTree
   */
	public CheckTreeManager(JTree tree) {
		this.tree = tree;
		selectionModel = new CheckTreeSelectionModel(tree.getModel());
		tree.setCellRenderer(new CheckTreeCellRenderer(tree.getCellRenderer(),
						selectionModel));
		tree.addMouseListener(this);
		tree.addMouseMotionListener(this);
		selectionModel.addTreeSelectionListener(this);
	}

  /**
   * Handles mouse moved events.
   *
   * @param e the mouse event
   */
	public void mouseMoved(MouseEvent e) {
		TreePath path = tree.getPathForLocation(e.getX(), e.getY());
		if (path == null) return;
		if (e.getX() > tree.getPathBounds(path).x + hotspot-3 ||
						e.getX() < tree.getPathBounds(path).x + 2)
			tree.setCursor(Cursor.getDefaultCursor());
		else {
			tree.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		}
	}

  /**
   * Handles mouse click events.
   *
   * @param e the mouse event
   */
	public void mouseClicked(MouseEvent e) {
		TreePath path = tree.getPathForLocation(e.getX(), e.getY());
		if (path == null) return;
		if (e.getX() > tree.getPathBounds(path).x + hotspot) return;

		boolean selected = selectionModel.isPathOrAncestorSelected(path);
		try {
			ignoreEvents = true;
			if (selected) {
				selectionModel.removeSelectionPath(path);
			}
			else {
				selectionModel.addSelectionPath(path);
			}
		}
		finally {
			ignoreEvents = false;
			tree.treeDidChange();
		}
	}

	public CheckTreeSelectionModel getSelectionModel() {
		return selectionModel;
	}

	public void valueChanged(TreeSelectionEvent e) {
		if (!ignoreEvents) tree.treeDidChange();
	}

   public void mouseDragged(MouseEvent e){/** empty block */}
}
/*
 * Open Source Physics software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License (GPL) as
 * published by the Free Software Foundation; either version 2 of the License,
 * or(at your option) any later version.
 *
 * Code that uses any portion of the code in the org.opensourcephysics package
 * or any subpackage (subdirectory) of this package must must also be be
 * released under the GNU GPL license.
 *
 * This software is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston MA 02111-1307 USA or view the license online at
 * http://www.gnu.org/copyleft/gpl.html
 *
 * Copyright (c) 2007 The Open Source Physics project
 * http://www.opensourcephysics.org
 */
